package templates

import (
	_const "gitee.com/lstack_light/go-light/internal/pkg/global"
	"log"
	"os"
	"strings"
	"text/template"
)

/**
  @author: light
  @since: 2023/9/3
  @desc: 路由模板
*/

var _ Template = &Router{}

type Router struct {
	Receiver *Receiver
	TemplateParams
}

func (r *Router) Execute(eventType _const.TemplateEventType) error {
	switch eventType {
	case _const.InitEvent:
		return r.Init()
	case _const.GenerateEvent:
		return r.Generate()
	}
	return nil
}

func (r *Router) Init() error {
	routerData := []byte("package controller\n\nimport (\n\t\"gitee.com/lstack_light/go-light/pkg/middleware\"\n\t\"gitee.com/lstack_light/go-light/pkg/server\"\n\t\"{{.Module}}/internal/service\"\n\t\"{{.Module}}/internal/service/impl\"\n)\n\ntype {{.Self}} struct {\n\tservice.{{.Name}}Service\n}\n\nvar {{.Name}}Router = server.NewController(\"/api/users\", &{{.Self}}{\n\t{{.Name}}Service: impl.{{.Name}}ServiceImpl,\n}, middleware.Logger(true))\n\nfunc ({{.SelfPrefix}} *{{.Self}}) FindAll() {\n\t{{.Name}}Router.Get(\"\", {{.SelfPrefix}}.{{.Name}}Service.FindAll)\n}\n\nfunc ({{.SelfPrefix}} *{{.Self}}) FindOne() {\n\t{{.Name}}Router.Get(\"/:id\", {{.SelfPrefix}}.{{.Name}}Service.FindOne)\n}\n\nfunc ({{.SelfPrefix}} *{{.Self}}) CreateOne() {\n\t{{.Name}}Router.Post(\"\", {{.SelfPrefix}}.{{.Name}}Service.CreateOne)\n}\n\nfunc ({{.SelfPrefix}} *{{.Self}}) UpdateOne() {\n\t{{.Name}}Router.Put(\"/:id\", {{.SelfPrefix}}.{{.Name}}Service.UpdateOne)\n}\n\nfunc ({{.SelfPrefix}} *{{.Self}}) DeleteOne() {\n\t{{.Name}}Router.Delete(\"/:id\", {{.SelfPrefix}}.{{.Name}}Service.DeleteOne)\n}")
	err := os.WriteFile(r.TemplateName, routerData, 0644)
	if err != nil {
		log.Fatal("创建路由层模板文件失败：", err)
		return err
	}
	return r.Receiver.next.Execute(_const.InitEvent)
}

func (r *Router) Generate() error {
	file, createErr := os.Create(r.OutputFile)
	if createErr != nil {
		log.Fatal(createErr)
		return createErr
	}
	// 读取模板文件
	tmpl, tempErr := template.ParseFiles(r.TemplateName)
	if tempErr != nil {
		log.Fatal("解析路由层模板失败：", tempErr)
		return tempErr
	}
	// 定义引用变量
	type Temp struct {
		Name       string
		Module     string
		Self       string
		SelfPrefix string
	}
	temp := Temp{
		Name:       r.Name,
		Module:     r.Module,
		Self:       r.Name + "Controller",
		SelfPrefix: strings.ToLower(r.Name)[0:1],
	}
	// 执行模板填充并写入输出文件
	err := tmpl.Execute(file, temp)
	if err != nil {
		log.Fatal(err)
		return err
	}
	// 删除模板文件
	_ = os.RemoveAll(r.TemplateName)
	log.Println("Go文件已生成：", r.OutputFile)
	return r.Receiver.next.Execute(_const.GenerateEvent)
}
